# ##############################
from chiori import Plugin, Ui
from libs.vk import get_ids
from libs.utils import clear_text
from datetime import datetime
import re, shutil
# ##############################

p = Plugin(name='анализ диалогов', path='data/chats_cache/', backend='vk_cli',
	sp=['vk'])


# func
# ====

async def add_data(u, data, res):
	"""дбавляет данные в словарь
	:param u: peer_id
	:param data: словарь с данными
	:param res: список сообщений полученный при помощи API

	:return: data с дополненными данными"""

	for m in res:
		t = datetime.fromtimestamp(m['date']).strftime('%x')
		uid = str(m["from_id"])
		text = clear_text(m['text'])

		if uid == str(u):
			index = 1
		else:
			index = 0

		# самые популярные дни
		if t in data['dc']:
			data['dc'][t] += 1
		else:
			data['dc'][t] = 1

		data['mc'][index] += 1
		data['wc'][index] += len(text.split())

		ct = []

		for x in text.split():

			if not x:
				continue


			if x[-1] in ['.', ',']:
				x = x[:-1]

			if len(x) < 3:
				continue

			if x.count(','):
				for part in x.split(','):
					ct.append(part.strip())
			else:
				ct.append(x)

		for x in ct:
			if x in data['words'][index]:
				data['words'][index][x] += 1
			else:
				data['words'][index][x] = 1

	return data


async def gen_stats(u, ctx, peer_id, debug=False):
	"""получает статистику диалога
	:oaram u: экземпляр chiori.UI
	:param ctx: экземпляр контекста
	:param peer_id: id назначения
	:para, debug: проводить ли анализ для всего диалога

	:return: словарь с данными чата"""
	ata = {'mc':[0, 0], 'dc':{}, 'wc':[0, 0], 'attachs':[], 'words':[{}, {}]}

	res = await ctx.request('messages.getHistory', count=200, peer_id=peer_id)
	if not res['error']:
		r = res['response']
		i = r['count']//200
		data = await add_data(peer_id, data, r['items'])

		if not debug:
			for x in range(i):
				res = await ctx.request('messages.getHistory', count=200,
							peer_id=peer_id, offset=200*(x+1))
				if res['error']:
					continue

				u.progress_bar(x, i, 'get messages..')

				data = await add_data(peer_id, data, res['response']['items'])

	return data


def get_progre_line(size, a, b):
	sep_on = round(size*(a/(a+b)))
	sep_off = size-sep_on

	if a > b:
		return f'{p.l.lcyan}{"─"*sep_on}{p.l.red}{"─"*sep_off}{p.l.reset}'
	else:
		return f'{p.l.cyan}{"─"*sep_on}{p.l.lred}{"─"*sep_off}{p.l.reset}'


def two_lines_form(size, lines=[]):
	size -= 2

	row = f' +{"─"*(size-2)}+ '

	print(row)
	for x in lines:
		p = re.search(r'<[0-9]*/[0-9]*>', x)

		if x.count('<|>') == 1:
			text = list(map(lambda x: x.strip(), x.split('<|>')))
			lt = size-4-sum(map(len, text))

			print(f' │ {text[0]}{" "*lt}{text[1]} │')

		elif p:
			data = map(int, p[0][1:-1].split('/'))

			text = list(map(lambda x: x.strip(), x.split(p[0])))
			lt = size-6-sum(map(len, text))
			l = get_progre_line(lt, *data)

			print(f' │ {text[0]} {l} {text[1]} │')


		else:
			print(f' │ {x}{" "*(size-4-len(x))} │')

	print(row)


# commands
# ========

@p.command('<a(nalys) c(hat)>', usage='[ids] сделать анализ чата')
async def analysChat(event, ctx):
	u = Ui()
	lines = []


	for uid in await get_ids(event, ctx):
		res = await gen_stats(u, ctx, uid)

		lines.append(f'анализ диалога: {event.get("from.id")}<|>{uid}')

		# кол-ов сообщений
		# ================

		mc = res["mc"]
		wc = res['wc']
		mp = round(mc[0]/sum(mc)*100, 2)
		wp = round(wc[0]/sum(wc)*100, 2)

		uc0 = len(list(filter(lambda x: x[1] == 1, res['words'][0].items())))
		uc1 = len(list(filter(lambda x: x[1] == 1, res['words'][1].items())))
		uc = uc0 + uc1
		ucp = round(uc0/uc*100, 2)

		lines.append(f'всего {sum(mc)} сообщений / {sum(wc)} слов ({uc} уникальных)')
		lines.append(f'в среднем: {round(wc[0]/mc[0], 2)}<|>{round(wc[1]/mc[1],2)}')
		lines.append(f'{mc[0]} ({mp}%) <{mc[0]}/{mc[1]}> {mc[1]}')
		lines.append(f'{wc[0]} ({wp}%) <{wc[0]}/{wc[1]}> {wc[1]}')
		lines.append(f'{uc0} ({ucp}%) <{uc0}/{uc1}> {uc1}')

		wl = sorted(res["words"][0].items(), key=lambda x: x[1], reverse=True)
		wl1 = sorted(res["words"][1].items(), key=lambda x: x[1], reverse=True)

		lines.append('самые частые слова:')
		for x in range(15):
			lines.append(f'{wl[x]} {wl[15+x]} <|> {wl1[x]} {wl1[15+x]}')



		# most active days
		# ================

		i = 0
		mm = max(res['dc'].values())

		lines.append('')
		lines.append('самые активные дни:')
		for k, v in sorted(res['dc'].items(), key=lambda x: x[1], reverse=True):
			i += 1
			lines.append(f'{k} <{v}/{mm}> {v}')
			if i >= 15:
				break

	two_lines_form(shutil.get_terminal_size()[0], lines)
